#ifndef HTTP_CLIENT_H
#define HTTP_CLIENT_H

#include <string>
#include <curl/curl.h>
#include <json/json.h>

struct HttpResponse {
    std::string body;
    long status_code;
    bool success;
};

class HttpClient {
private:
    CURL* curl;

    static size_t WriteCallback(void* contents, size_t size, size_t nmemb, std::string* response) {
        size_t total_size = size * nmemb;
        response->append((char*)contents, total_size);
        return total_size;
    }

public:
    HttpClient() {
        curl = curl_easy_init();
        if (!curl) {
            throw std::runtime_error("Failed to initialize CURL");
        }
    }

    ~HttpClient() {
        if (curl) {
            curl_easy_cleanup(curl);
        }
    }

    HttpResponse post(const std::string& url, const std::string& json_data, const std::vector<std::string>& headers = {}) {
        HttpResponse response;
        response.success = false;

        if (!curl) {
            response.body = "CURL not initialized";
            return response;
        }

        curl_easy_reset(curl);

        std::string response_body;

        curl_easy_setopt(curl, CURLOPT_URL, url.c_str());
        curl_easy_setopt(curl, CURLOPT_POSTFIELDS, json_data.c_str());
        curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, WriteCallback);
        curl_easy_setopt(curl, CURLOPT_WRITEDATA, &response_body);

        struct curl_slist* header_list = nullptr;
        header_list = curl_slist_append(header_list, "Content-Type: application/json");

        for (const auto& header : headers) {
            header_list = curl_slist_append(header_list, header.c_str());
        }

        curl_easy_setopt(curl, CURLOPT_HTTPHEADER, header_list);

        CURLcode res = curl_easy_perform(curl);

        if (res == CURLE_OK) {
            curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &response.status_code);
            response.body = response_body;
            response.success = (response.status_code >= 200 && response.status_code < 300);
        } else {
            response.body = curl_easy_strerror(res);
            response.status_code = 0;
        }

        curl_slist_free_all(header_list);
        return response;
    }

    HttpResponse get(const std::string& url, const std::vector<std::string>& headers = {}) {
        HttpResponse response;
        response.success = false;

        if (!curl) {
            response.body = "CURL not initialized";
            return response;
        }

        curl_easy_reset(curl);

        std::string response_body;

        curl_easy_setopt(curl, CURLOPT_URL, url.c_str());
        curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, WriteCallback);
        curl_easy_setopt(curl, CURLOPT_WRITEDATA, &response_body);

        struct curl_slist* header_list = nullptr;

        for (const auto& header : headers) {
            header_list = curl_slist_append(header_list, header.c_str());
        }

        if (header_list) {
            curl_easy_setopt(curl, CURLOPT_HTTPHEADER, header_list);
        }

        CURLcode res = curl_easy_perform(curl);

        if (res == CURLE_OK) {
            curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &response.status_code);
            response.body = response_body;
            response.success = (response.status_code >= 200 && response.status_code < 300);
        } else {
            response.body = curl_easy_strerror(res);
            response.status_code = 0;
        }

        curl_slist_free_all(header_list);
        return response;
    }
};

class QiniuLLMClient {
private:
    HttpClient http_client;
    std::string api_key;
    std::string api_endpoint;

public:
    QiniuLLMClient(const std::string& key, const std::string& endpoint)
        : api_key(key), api_endpoint(endpoint) {}

    std::string generate_response(const std::string& prompt, const std::string& model = "gpt-3.5-turbo") {
        Json::Value request;
        request["model"] = model;
        request["max_tokens"] = 1000;
        request["temperature"] = 0.7;
        request["stream"] = false;

        // 使用ChatGPT兼容的消息格式
        Json::Value messages(Json::arrayValue);
        Json::Value message;
        message["role"] = "user";
        message["content"] = prompt;
        messages.append(message);
        request["messages"] = messages;

        Json::StreamWriterBuilder builder;
        builder["indentation"] = "";  // 去掉缩进
        std::string json_data = Json::writeString(builder, request);

        std::vector<std::string> headers = {
            "Authorization: Bearer " + api_key,
            "Content-Type: application/json"
        };

        HttpResponse response = http_client.post(api_endpoint, json_data, headers);

        if (response.success) {
            Json::Value json_response;
            Json::Reader reader;

            if (reader.parse(response.body, json_response)) {
                if (json_response.isMember("choices") && json_response["choices"].isArray() &&
                    json_response["choices"].size() > 0) {
                    // ChatGPT格式响应
                    Json::Value choice = json_response["choices"][0];
                    if (choice.isMember("message") && choice["message"].isMember("content")) {
                        return choice["message"]["content"].asString();
                    }
                    // 兼容旧格式
                    if (choice.isMember("text")) {
                        return choice["text"].asString();
                    }
                } else if (json_response.isMember("response")) {
                    return json_response["response"].asString();
                }
            }
        } else {
            std::cerr << "HTTP请求失败: " << response.status_code << " - " << response.body << std::endl;
        }

        return "抱歉，我现在无法回应，请稍后再试。";
    }
};

class QiniuSTTClient {
private:
    HttpClient http_client;
    std::string api_key;
    std::string stt_endpoint;

public:
    QiniuSTTClient(const std::string& key, const std::string& endpoint)
        : api_key(key), stt_endpoint(endpoint) {}

    std::string speech_to_text(const std::string& audio_data, const std::string& format = "wav") {
        Json::Value request;
        request["audio"] = audio_data;
        request["format"] = format;
        request["language"] = "zh-CN";

        Json::StreamWriterBuilder builder;
        builder["indentation"] = "";  // 去掉缩进
        std::string json_data = Json::writeString(builder, request);

        std::vector<std::string> headers = {
            "Authorization: Bearer " + api_key,
            "Content-Type: application/json"
        };

        HttpResponse response = http_client.post(stt_endpoint, json_data, headers);

        if (response.success) {
            Json::Value json_response;
            Json::Reader reader;

            if (reader.parse(response.body, json_response)) {
                if (json_response.isMember("text")) {
                    return json_response["text"].asString();
                }
            }
        }

        return "";
    }
};

class QiniuTTSClient {
private:
    HttpClient http_client;
    std::string api_key;
    std::string tts_endpoint;

public:
    QiniuTTSClient(const std::string& key, const std::string& endpoint)
        : api_key(key), tts_endpoint(endpoint) {}

    std::string text_to_speech(const std::string& text, const std::string& voice = "default") {
        Json::Value request;
        request["text"] = text;
        request["voice"] = voice;
        request["format"] = "wav";
        request["sample_rate"] = 16000;

        Json::StreamWriterBuilder builder;
        builder["indentation"] = "";  // 去掉缩进
        std::string json_data = Json::writeString(builder, request);

        std::vector<std::string> headers = {
            "Authorization: Bearer " + api_key,
            "Content-Type: application/json"
        };

        HttpResponse response = http_client.post(tts_endpoint, json_data, headers);

        if (response.success) {
            Json::Value json_response;
            Json::Reader reader;

            if (reader.parse(response.body, json_response)) {
                if (json_response.isMember("audio_data")) {
                    return json_response["audio_data"].asString();
                }
            }
        }

        return "";
    }
};

#endif